package com.dji.sample.wayline.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dji.sample.common.util.KmlUtil;
import com.dji.sample.common.util.MinioUtil;
import com.dji.sample.common.util.kmlModel.TravelRecordRequest;
import com.dji.sample.manage.dao.DevicePositionMapper;
import com.dji.sample.manage.model.dto.DeviceDTO;
import com.dji.sample.manage.model.entity.DevicePlayLineCacheEntity;
import com.dji.sample.manage.model.entity.DevicePositionEntity;
import com.dji.sample.manage.model.enums.DeviceDomainEnum;
import com.dji.sample.manage.service.DevicePlayLineCacheService;
import com.dji.sample.manage.service.DevicePositionService;
import com.dji.sample.manage.service.IDeviceService;
import com.dji.sample.wayline.dao.DevicePlayTaskDetailMapper;
import com.dji.sample.wayline.dao.IWaylineFileMapper;
import com.dji.sample.wayline.model.entity.DevicePlayTaskEntity;

import com.dji.sample.wayline.model.entity.WaylineFileEntity;
import com.dji.sample.wayline.model.entity.WaylineInfoEntity;
import com.dji.sample.wayline.service.DevicePlayTaskDetailService;
import com.dji.sample.wayline.service.WaylineInfoService;
import io.minio.ObjectWriteResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yjt
 * @since 2022-10-26
 */
@Service
public class DevicePlayTaskDetailServiceImpl extends ServiceImpl<DevicePlayTaskDetailMapper, DevicePlayTaskEntity> implements DevicePlayTaskDetailService {

    @Autowired
    private IWaylineFileMapper waylineFileMapper;

    @Autowired
    IDeviceService deviceService;

    @Autowired
    DevicePlayTaskDetailService devicePlayTaskDetailService;

    @Autowired
    DevicePositionService devicePositionService;

    @Autowired
    DevicePlayLineCacheService devicePlayLineCacheService;

    @Autowired
    DevicePositionMapper devicePositionMapper;

    @Autowired
    KmlUtil kmlUtil;

    @Autowired
    MinioUtil minioUtil;

    @Autowired
    WaylineInfoService waylineInfoService;

    @Override
    public Long startTask(Long lineId, String deviceNo, Long orgId, String orgCode, String username) {
        WaylineFileEntity waylineFile = waylineFileMapper.selectById(lineId);
        if (waylineFile == null) {
            throw new RuntimeException("航线不存在");
        }
        if (!waylineFile.getDeviceNo().equals(deviceNo)) {
            throw new RuntimeException("不是您的任务");
        }
        WaylineInfoEntity waylineInfoEntity = waylineInfoService.getOne(new LambdaQueryWrapper<WaylineInfoEntity>().eq(WaylineInfoEntity::getUniKey, waylineFile.getUniKey()));
        if(waylineInfoEntity==null || waylineInfoEntity.getStatus()!=1){
            throw new RuntimeException("该任务未通过审核");
        }
        if (waylineFile.getStartTime() != null && new Date().compareTo(waylineFile.getStartTime()) < 0) {
            throw new RuntimeException("任务还未到开始时间");
        }
        if (waylineFile.getEndTime() != null && new Date().compareTo(waylineFile.getStartTime()) > 0) {
            throw new RuntimeException("任务已结束");
        }
        Optional<DeviceDTO> optional = deviceService.getDeviceByNo(deviceNo);
        if (optional.isEmpty()) {
            throw new RuntimeException("设备不存在");
        }
        if (!optional.get().getDomain().equals(DeviceDomainEnum.SUB_DEVICE.getDesc())) {
            throw new RuntimeException("设备类型错误");
        }
        List<DevicePlayTaskEntity> list = devicePlayTaskDetailService.list(new LambdaQueryWrapper<DevicePlayTaskEntity>().eq(DevicePlayTaskEntity::getLineId, waylineFile.getId()).eq(DevicePlayTaskEntity::getDeviceNo, deviceNo).eq(DevicePlayTaskEntity::getStatus, 0));
        if (list.size() > 0) {
            throw new RuntimeException("当前存在未结束的任务不可重新开始");
        }
        //添加任务执行记录
        DevicePlayTaskEntity devicePlayTaskEntity = new DevicePlayTaskEntity();
        devicePlayTaskEntity.setDeviceNo(deviceNo);
        devicePlayTaskEntity.setDeviceSn(optional.get().getDeviceSn());
        devicePlayTaskEntity.setLineId(waylineFile.getId().longValue());
        devicePlayTaskEntity.setLineName(waylineFile.getName());
        devicePlayTaskEntity.setOrgId(orgId);
        devicePlayTaskEntity.setOrgCode(orgCode);
        devicePlayTaskEntity.setCreateBy(username);
        devicePlayTaskEntity.setStartTime(new Date());
        devicePlayTaskEntity.setStatus(0);
        DevicePositionEntity devicePosition = devicePositionService.getLastDevicePosition(optional.get().getDeviceSn(), LocalDateTime.now().plusSeconds(-66).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        if (devicePosition == null) {
            throw new RuntimeException("获取当前坐标失败");
        }
        devicePlayTaskEntity.setStartPositionId(devicePosition.getId().longValue());
        devicePlayTaskDetailService.save(devicePlayTaskEntity);
        return devicePlayTaskEntity.getId();
    }

    @Override
    public void endTask(Long taskId, String deviceNo) {
        DevicePlayTaskEntity devicePlayTaskEntity = devicePlayTaskDetailService.getById(taskId);
        if (devicePlayTaskEntity == null) {
            throw new RuntimeException("任务结束失败，数据不存在");
        }
        Optional<DeviceDTO> optional = deviceService.getDeviceByNo(deviceNo);
        if (optional.isEmpty()) {
            throw new RuntimeException("设备不存在");
        }
        DevicePositionEntity devicePosition = devicePositionService.getLastDevicePosition(optional.get().getDeviceSn(), LocalDateTime.now().plusSeconds(-66).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        if (devicePosition == null) {
            throw new RuntimeException("获取当前坐标失败");
        }
        devicePlayTaskEntity.setEndPositionId(devicePosition.getId().longValue());
        devicePlayTaskEntity.setEndTime(new Date());
        devicePlayTaskEntity.setStatus(1);
        devicePlayTaskDetailService.updateById(devicePlayTaskEntity);
    }

    @Override
    public List<DevicePlayTaskEntity> unFinishTask(Long lineId, String deviceNo) {
        List<DevicePlayTaskEntity> list = devicePlayTaskDetailService.list(new LambdaQueryWrapper<DevicePlayTaskEntity>().eq(DevicePlayTaskEntity::getDeviceNo, deviceNo).eq(lineId != null, DevicePlayTaskEntity::getLineId, lineId).eq(DevicePlayTaskEntity::getStatus, 0));
        if (list.size() > 0) {
            throw new RuntimeException("当前存在未结束的任务不可重新开始");
        }
        return list;
    }

    @Override
    public String getOssPath(Long id) throws Exception {
        DevicePlayTaskEntity devicePlayTaskEntity = devicePlayTaskDetailService.getById(id);
        if (devicePlayTaskEntity == null) {
            throw new RuntimeException("数据不存在");
        }
        DevicePlayLineCacheEntity devicePlayLineCacheEntity = devicePlayLineCacheService.findByTaskId(id);
        if (devicePlayLineCacheEntity == null) {
            List<DevicePositionEntity> list = devicePositionMapper.selectList(new LambdaQueryWrapper<DevicePositionEntity>().ge(DevicePositionEntity::getId, devicePlayTaskEntity.getStartPositionId()).le(DevicePositionEntity::getId, devicePlayTaskEntity.getEndPositionId()).eq(DevicePositionEntity::getDeviceSn, devicePlayTaskEntity.getDeviceSn()));
            if (list.isEmpty()) {
                throw new IllegalArgumentException("未查询到轨迹点位数据");
            }
            String name = String.format("%s_%s", devicePlayTaskEntity.getDeviceSn(), devicePlayTaskEntity.getId());
            ObjectWriteResponse objectWriteResponse = kmlUtil.setTravelsKml(conventList(list), name);
            if (objectWriteResponse == null) {
                throw new IllegalArgumentException("航线获取失败");
            }
            DevicePlayLineCacheEntity devicePlayLineCache = new DevicePlayLineCacheEntity();
            devicePlayLineCache.setTaskId(devicePlayTaskEntity.getId());
            devicePlayLineCache.setObjectKey(objectWriteResponse.object());
            devicePlayLineCache.setCreateTime(new Date());
            devicePlayLineCacheService.save(devicePlayLineCache);
            return minioUtil.preview(objectWriteResponse.object());
        }
        return minioUtil.preview(devicePlayLineCacheEntity.getObjectKey());
    }

    public List<TravelRecordRequest> conventList(List<DevicePositionEntity> list) {
        List<TravelRecordRequest> travelRecordRequests = new ArrayList<>();
        TravelRecordRequest travelRecordRequest = null;
        for (DevicePositionEntity devicePosition : list) {
            travelRecordRequest = new TravelRecordRequest(devicePosition.getLongitude(), devicePosition.getLatitude(), devicePosition.getHeight());
            travelRecordRequests.add(travelRecordRequest);
        }
        return travelRecordRequests;
    }
}
